package site.teamo.biu.net.common.util;

import cn.hutool.core.net.NetUtil;
import site.teamo.biu.net.common.constant.Protocol;

import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * @author haocongshun
 * @date 2023/02/28 15:52:02
 */
public record HostPort(Protocol protocol, String host, int port) {
    public HostPort {
        if (!NetUtil.isValidPort(port)) {
            throw new IllegalArgumentException("不合法的端口号:" + port);
        }
    }

    //udp协议直接返回0
    //测试联通性和延迟，返回值小于0代表无法连接
    public long testDelay() {
        if (protocol.isUdp) {
            return 0;
        }
        long startTime = System.currentTimeMillis();
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(host, port), 1000);
            return System.currentTimeMillis() - startTime;
        } catch (Exception e) {
            return -1;
        }
    }

    public HostPort setProtocol(Protocol protocol) {
        return of(protocol, this.host, this.port);
    }

    public String toUrl() {
        return protocol.scheme + host + ":" + port;
    }

    public static HostPort of(Protocol protocol, String host, int port) {
        return new HostPort(protocol, host, port);
    }

    public static HostPort of(String host, int port) {
        return new HostPort(Protocol.TCP_GENERIC, host, port);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        HostPort hostPort = (HostPort) o;

        if (port != hostPort.port) {
            return false;
        }
        if (protocol != hostPort.protocol) {
            return false;
        }
        return host.equals(hostPort.host);
    }

    @Override
    public int hashCode() {
        int result = protocol.hashCode();
        result = 31 * result + (host + ":" + port).hashCode();
        return result;
    }
}
